package com.pandaroid.pandaclock;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.util.Log;
import android.widget.RemoteViews;
//
/*
 * [2011/04/19]
 * 1.시간 업데이트 체크를 1초에 한번씩 수행 후 변경 시 업데이트를 수행하는 방식에서
 *		한번 수행 후 다음번 업데이트를 60초 후로 설정하는 방법으로 변경
 *		(위젯 업데이트를 서비스를 사용하는 방법도 있으나 AlarmManager를 사용하는 방법이 자원을 덜 사용할 것으로 판단됨)
 * 2.manifest intent-filter와 onReceive함수 수정으로 최초 시간 업데이트를 수행하는 상활 고려=>잘 안됨
 * 		1)
 */


/**
 * AppWidgetProvider를 상속받은 Class로 broascast 형태로 다른 component 들과 통신을 한다.
 * (AppWidgetProvider가 BroadcastReceiver를 상속하였기 때문)
 * AppWidget이 update, enabled, disabled, delete 되었을 때 broadcast 형태로 callback이 불린다.
 * 
 * com.anclick.mywatch
 * MyWatchProvider.java
 *
 * @author junhwan_kim
 * @date 2011. 4. 29. 오후 2:16:51
 * @Version
 */
public class PandaClockProvider extends AppWidgetProvider {

	private static final String TAG = "PandaClockNo1";
	private static String mDateFormat = "EEE MMM dd yyyy hh mm a";	/// 요일 월 일 년 시 분 APM
	
	/**
	 * Called in response to the ACTION_APPWIDGET_UPDATE broadcast when this AppWidget provider is being asked to provide RemoteViews for a set of AppWidgets. 
	 * AppWidget의 속성(Meta data)에서 지정해준 updatePeriodMillis 값에 따라 주기적으로 호출된다.
	 * 또한 처음 widget이 화면에 붙을 때, init() 작업을 해주기 위해서도 call 된다.
	 * (Configuration activity를 따로 두었다면, 처음 붙을 때 불리지는 않음. 대신 Configuration Activity가 init를 함.)
	 * 
	 * @see android.appwidget.AppWidgetProvider#onUpdate(android.content.Context, android.appwidget.AppWidgetManager, int[])
	 * @Method onUpdate
	 * @param context
	 * @param appWidgetManager
	 * @param appWidgetIds
	 *
	 * @author junhwan_kim
	 * @date 2011. 4. 29. 오후 2:16:56
	 */
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
		/// widget id 쓰도록 변경, 2011.05.06, junhwan_kim
		final int N = appWidgetIds.length;
        for (int i=0; i<N; i++) {
            int appWidgetId = appWidgetIds[i];
            Log.d(TAG, "onUpdate(" + appWidgetId + ")");
            updateWidget(context, appWidgetManager, appWidgetId);
        }
        
        super.onUpdate(context, appWidgetManager, appWidgetIds);
	}
	
	/**
	 * Implements onReceive(Context, Intent) to dispatch calls to the various other methods on AppWidgetProvider.
	 * 일반적인 broadcasting receiver
	 * 다른 callback들 보다 먼저 불림.
	 * 
	 * @see android.appwidget.AppWidgetProvider#onReceive(android.content.Context, android.content.Intent)
	 * @Method onReceive
	 * @param context
	 * @param intent
	 *
	 * @author junhwan_kim
	 * @date 2011. 4. 29. 오후 2:17:00
	 */
	@Override
	public void onReceive(Context context, Intent intent) {
		Log.i(TAG, "onReceive()");
		
		// TIME_TICK broadcast를 받는 경우 widget을 update하도록 수정, 2011.05.03, junhwan_kim
		context.startService(new Intent(context, PandaClockService.class));
		
		String action = intent.getAction();
        if (action.equals(Intent.ACTION_TIME_TICK)) {
        	Log.d(TAG, "ACTION_TIME_TICK");
        	
        	AppWidgetManager gm = AppWidgetManager.getInstance(context);

        	Map<String,?> map = PandaClockPreferences.getAllWidgetId(context);	// widget id를 map으로 가져온다.
            Set<String> set = map.keySet();		// hm의 키값들을 Set(집합)으로 값을 가져옵니다.
            Object []hmKeys = set.toArray();	// Set의 값들을 Object 배열로 변환합니다.
            
            // Object 배열의 요소(키값이죠.)이걸로 hm의 값을 가져와서 출력합니다.
            for(int i =  0; i < hmKeys.length; i++) {
                String key = (String)hmKeys[i];
                updateWidget(context, gm, Integer.parseInt(key));
            }
        }
        
        super.onReceive(context, intent);
	}

	/**
	 * Called in response to the ACTION_APPWIDGET_ENABLED broadcast when the a AppWidget for this provider is instantiated. 
	 * App Widget이 처음 생성될 때 불린다.
	 * 같은 위젯을 여러개 띄우면, 첫번째 위젯을 띄울 때만 호출이 된다.
	 * 
	 * @see android.appwidget.AppWidgetProvider#onEnabled(android.content.Context)
	 * @Method onEnabled
	 * @param context
	 *
	 * @author junhwan_kim
	 * @date 2011. 4. 29. 오후 2:17:06
	 */
	@Override
	public void onEnabled(Context context) {
		Log.i(TAG, "onEnabled()");

		super.onEnabled(context);
	}

	/**
	 * Called in response to the ACTION_APPWIDGET_DELETED broadcast when one or more AppWidget instances have been deleted. 
	 * App Widget이 Widget host로 부터 삭제될 때 불린다.
	 * 
	 * @see android.appwidget.AppWidgetProvider#onDeleted(android.content.Context, int[])
	 * @Method onDeleted
	 * @param context
	 * @param appWidgetIds
	 *
	 * @author junhwan_kim
	 * @date 2011. 4. 29. 오후 2:17:11
	 */
	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {
		/// 해당 id를 삭제한다., 2011.05.06, junhwan_kim
		final int N = appWidgetIds.length;
        for (int i=0; i<N; i++) {
        	Log.d(TAG, "onDeleted(" + appWidgetIds[i] + ")");
        	PandaClockPreferences.removePref(context, appWidgetIds[i]);
        	PandaClockPreferences.removeWidgetId(context, appWidgetIds[i]);
        }
        
        super.onDeleted(context, appWidgetIds);
	}

	/**
	 * Called in response to the ACTION_APPWIDGET_DISABLED broadcast, which is sent when the last AppWidget instance for this provider is deleted. 
	 * App Widget이 삭제될 때 불린다.
	 * 가장 마지막에 남아있는 App Widget이 detach 되었을 때 호출된다.
	 * 
	 * @see android.appwidget.AppWidgetProvider#onDisabled(android.content.Context)
	 * @Method onDisabled
	 * @param context
	 *
	 * @author junhwan_kim
	 * @date 2011. 4. 29. 오후 2:17:15
	 */
	@Override
	public void onDisabled(Context context) {
		Log.i(TAG, "onDisabled()");

		/// 추가된 앱 위젯별로 설정한 디렉토리 정보 초기화
		PandaClockPreferences.removeAllPref(context);
		PandaClockPreferences.removeAllWidgetId(context);
		super.onDisabled(context);
	}

	/**
	 * AppWidget에 뿌려질 뷰를 업데이트
	 * 
	 * @Method updateWidget
	 * @param context
	 * @param bForce
	 *
	 * @author junhwan_kim
	 * @date 2011. 4. 29. 오후 2:17:20
	 */
	static public void updateWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
		
		SimpleDateFormat sdf = new SimpleDateFormat(mDateFormat, Locale.US);
		String sDate = sdf.format(new Date());
		
		Log.d(TAG, "updateWidget(" + appWidgetId + ")");
		
		/// 요일 월 일 년 시 분 APM
		String aDateTime[] = sDate.split(" ");	/// ex) "Tue May 03 2011 03 52
		
		String sDayOfWeek = aDateTime[0].toLowerCase();		/// 요일
		String sMonth = aDateTime[1].toLowerCase();			/// 월
		String sDay10 = aDateTime[2].substring(0, 1);		/// 일1
		String sDay01 = aDateTime[2].substring(1, 2);		/// 일2
		String sYear = aDateTime[3];						/// 년
		String sHour10 = aDateTime[4].substring(0, 1);		/// 시1
		String sHour01 = aDateTime[4].substring(1, 2);		/// 시2
		String sMin10 = aDateTime[5].substring(0, 1);		/// 분1
		String sMin01 = aDateTime[5].substring(1, 2);		/// 분2
		String sAmPm = aDateTime[6].toLowerCase();			/// AMPM
		
		String[] prefValue = PandaClockPreferences.getPref(context, appWidgetId);
		
		/// 선택된 디렉토리 없을 때 대비
		String directory = prefValue[PandaClockPreferences.THEME];
		Log.d(TAG, "update widgetid : "+appWidgetId);
		
		/// Onclick Intent 등록 및 Widget ID 전달.
        Intent intent = new Intent(context, PandaClockConfigure.class);
        intent.setAction(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        intent.putExtra("SELECTED_WIDGET_ID", appWidgetId);
         
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout);
        //PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);	//★★★★★ 무지중요
        PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        views.setOnClickPendingIntent(R.id.appwidgetlayout, pendingIntent);
        
		/// Theme 비교
        String theme = "";
        if (directory.equals(PandaClockConfigure.WHITE_THEME)) {
        	theme = "w_";
        } else if (directory.equals(PandaClockConfigure.BLACK_THEME)) {
        	theme = "b_";
        }
        
    	Resources res = context.getResources();
    	
    	views.setImageViewResource(R.id.imgHour10, res.getIdentifier(theme + "num_" + sHour10 + "_0", "drawable", context.getPackageName()));	// 10시간 단위 표시 뷰
    	views.setImageViewResource(R.id.imgHour01, res.getIdentifier(theme + "num_" + sHour01 + "_0", "drawable", context.getPackageName()));	// 01시간 단위 표시 뷰
    	views.setImageViewResource(R.id.imgColon, res.getIdentifier(theme + "colon", "drawable", context.getPackageName()));																// colon
    	views.setImageViewResource(R.id.imgMinute10, res.getIdentifier(theme + "num_" + sMin10 + "_0", "drawable", context.getPackageName()));	// 10분 단위 표시 뷰
    	views.setImageViewResource(R.id.imgMinute01, res.getIdentifier(theme + "num_" + sMin01 + "_0", "drawable", context.getPackageName()));	// 01분 단위 표시 뷰
		views.setImageViewResource(R.id.imgAPM, res.getIdentifier(theme + sAmPm, "drawable", context.getPackageName()));	// AM PM 표시 뷰.
		views.setImageViewResource(R.id.imgMonth, res.getIdentifier(theme + "month_" + sMonth, "drawable", context.getPackageName()));	// Month 표시 뷰
		views.setImageViewResource(R.id.imgDay10, res.getIdentifier(theme + "number_day_0" + sDay10, "drawable", context.getPackageName()));	// date1 표시 뷰
		views.setImageViewResource(R.id.imgDay01, res.getIdentifier(theme + "number_day_0" + sDay01, "drawable", context.getPackageName()));	// date2 표시 뷰
		views.setImageViewResource(R.id.imgDayOfWeek, res.getIdentifier(theme + "week_" + sDayOfWeek, "drawable", context.getPackageName()));	// day of week 표시 뷰
		views.setImageViewResource(R.id.imgYear, res.getIdentifier(theme + "year_" + sYear, "drawable", context.getPackageName()));	// Year 표시 뷰
		
		appWidgetManager.updateAppWidget(appWidgetId, views);
	}
}
